package thread.pool.exception;

import java.util.concurrent.*;

/**
 * 捕获线程池中的堆栈异常
 */
public class CatchException {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        threadPoolSubmitDefault();
        threadPoolExecuteDefault();
//        threadPoolSubmitGetDefault();
//        threadPoolSubmitTrace();
    }


    /**
     * 用juc包里的未封装线程池执行DivTask
     * 预期结果：5个
     * 实际输出结果： 4个，与预期结果不相符且没有异常堆栈打印
     * 100.0
     * 25.0
     * 33.0
     * 50.0
     */
    public static void threadPoolSubmitDefault() {
        ThreadPoolExecutor pools = new ThreadPoolExecutor(0, 10, 0L,
                TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
        for (int i = 0; i < 5; i++) {
            pools.submit(new DivTask(100, i));
        }
    }

    /**
     * 用juc包里的未封装线程池执行DivTask
     * 预期结果：5个
     * 实际输出结果： 主线程抛出异常并中断，与预期结果不相符且有部分异常堆栈打印
     Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
     at thread.pool.exception.DivTask.run(DivTask.java:14)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
     at java.lang.Thread.run(Thread.java:748)
     100.0
     25.0
     33.0
     50.0
     */
    public static void threadPoolExecuteDefault() {
        ThreadPoolExecutor pools = new ThreadPoolExecutor(0, 10, 0L,
                TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
        for (int i = 0; i < 5; i++) {
            pools.execute(new DivTask(100, i));
        }
    }

    /**
     * 用juc包里的未封装线程池执行DivTask
     * 预期结果：5个
     * 实际输出结果： 4个，与预期结果不相符且有部分异常堆栈打印
     Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
     at java.util.concurrent.FutureTask.report(FutureTask.java:122)
     at java.util.concurrent.FutureTask.get(FutureTask.java:192)
     at thread.pool.exception.CatchException.threadPoolSubmitGetDefault(CatchException.java:79)
     at thread.pool.exception.CatchException.main(CatchException.java:13)
     Caused by: java.lang.ArithmeticException: / by zero
     at thread.pool.exception.DivTask.run(DivTask.java:14)
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
     at java.lang.Thread.run(Thread.java:748)
     */
    public static void threadPoolSubmitGetDefault() throws ExecutionException, InterruptedException {
        ThreadPoolExecutor pools = new ThreadPoolExecutor(0, 10, 0L,
                TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
        for (int i = 0; i < 5; i++) {
            Future<?> submit = pools.submit(new DivTask(100, i));
            submit.get();
        }
    }

    /**
     *
     java.lang.Exception: Client stack trace
     at thread.pool.exception.TraceThreadPoolExecutor.clientTrace(TraceThreadPoolExecutor.java:32)
     at thread.pool.exception.TraceThreadPoolExecutor.execute(TraceThreadPoolExecutor.java:19)
     at thread.pool.exception.CatchException.threadPoolSubmitTrace(CatchException.java:87)
     at thread.pool.exception.CatchException.main(CatchException.java:14)
     Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
     at thread.pool.exception.DivTask.run(DivTask.java:14)
     at thread.pool.exception.TraceThreadPoolExecutor$1.run(TraceThreadPoolExecutor.java:46)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
     at java.lang.Thread.run(Thread.java:748)
     100.0
     25.0
     33.0
     50.0
     */
    public static void threadPoolSubmitTrace() {
        ThreadPoolExecutor pools = new TraceThreadPoolExecutor(0, 10, 0L,
                TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
        for (int i = 0; i < 5; i++) {
            pools.execute(new DivTask(100, i));
        }
    }

}
